.TITLE DLDRV .IDENT /07.03/ ; ; Copyright (c) 1995-1999 by Mentec, Inc., U.S.A. ; All rights reserved ; ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED ; OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; PREVIOUSLY MODIFIED BY: ; ; P. J. BEZEREDI ; R. T. PERRON ; P. J. CARR ; D. R. DONCHIN ; J. GALLANT ; G. MARIGOWDA ; ; MODIFIED FOR RSX-11M-PLUS VERSION 4.1 BY: ; ; PAUL K. M. WEISS 16-DEC-1987 7.02 ; ; PKW146 - SET KS.DIP SO $IODON WON'T DEALLOCATE UMRS ON ATTACH ; ; MARC J. NOEL 22-APR-1988 7.03 ; ; MJN015 - CLEAR KS.DIP BEFORE SETTING UP THE CONTROLLER INDEX ; ; RL11/RL01 DISK DRIVER ; ; .MCALL HWDDF$,PKTDF$,QIOSY$ HWDDF$ ;DEFINE HARDWARE REGISTERS PKTDF$ ;DEFINE I/O PACKET OFFSETS QIOSY$ ; ; EQUATED SYMBOLS ; RETRY= ^D<8> ;CONTROLLER ERROR RETRY COUNT RLCNT= ^D<7> ;NUMBER OF REGISTERS TO LOG ON ERROR RLBPT= ^D<512*20> ;BYTES PER RL01 SURFACE RLSPU= ^D<15> ;TIME FOR RL01 TO SPIN UP ; ; RL11 DEVICE REGISTER OFFSETS ; RLCS= 0 ;CONTROL STATUS REGISTER RLBA= 2 ;BUS ADDRESS REGISTER RLDA= 4 ;DISK ADDRESS REGISTER RLMP= 6 ;MULTI-PURPOSE REGISTER RLBAE= 10 ;BUS ADDRESS EXTENSION REGISTER ; ; RLCS BIT ASSIGNMENTS ; ERR= 100000 ;COMPOSITE ERROR DE= 040000 ;DRIVE ERROR NXM= 020000 ;NON-EXISTANT MEMORY DLT= 010000 ;DATA LATE HNF= 010000 ;HEADER NOT FOUND DCK= 004000 ;DATA CHECK ERROR HCRC= 004000 ;HEADER CRC ERROR OPI= 002000 ;OPERATION INCOMPLETE A17= 000040 ;EXTENDED ADDRESS BIT 17 A16= 000020 ;EXTENDED ADDRESS BIT 16 DS0= 000400 ;DRIVE SELECT 0 DS1= 001000 ;DRIVE SELECT 1 DRDY= 1 ;DRIVE READY WCHK= 2 ;WRITE CHECK FUNCTION WRITE= 2 ;WRITE OFFSET GSTS= 4 ;GET DRIVE STATUS FUNCTION SEEK= 6 ;SEEK FUNCTION RDH= 10 ;READ HEADERS FUNCTION READ= 14 ;READ DATA FUNCTION IE= 100 ;INTERRUPT ENABLE CRDY= 200 ;CONTROLLER READY ; ; RLDA STATUS CODES ; MRK= 1 ;MARKER BIT STS= 2 ;GET STATUS BIT SN= 4 ;SIGN BIT FOR SEEK RST= 10 ;DRIVE RESET BIT HS= 20 ;HEAD SELECT BIT FOR DIFFERENCE REV= 200!MRK ;REVERSE SEEK DIFFERENCE WORD ; ; RLMP GET STATUS BIT ASSIGNMENTS ; WDE= 100000 ;WRITE DATA ERROR CHE= 040000 ;CURRENT HEAD ERROR WLS= 020000 ;WRITE LOCK STATUS SKTO= 010000 ;SEEK TIMEOUT ERROR SPD= 004000 ;SPEED ERROR WGE= 002000 ;WRITE GATE ERROR VC= 001000 ;VOLUME CHECK DSE= 000400 ;DRIVE SELECT ERROR DT= 000200 ;DRIVE TYPE HSS= 000100 ;HEAD SELECT STATUS CO= 000040 ;COVER OPEN HH= 000020 ;HEADS HOME BH= 000010 ;BRUSHES HOME SLM= 000005 ;DRIVE IN SEEK-LINEAR MODE STATE ; ; DRIVE STATUS FLAGS ; RVSK= 200 ;REVERSE SEEK IN PROGRESS SDWN= 100 ;DRIVE ERROR SETTLE DOWN IN PROGRESS ; ; LOCAL DATA ; ; CONTROLLER IMPURE DATA TABLES ; THESE ARE INDEXED BY THE CONTROLLER NUMBER ; RTTBL: .BLKW R$$L11 ;RETRY COUNT FOR CURRENT OPERATION PRMSV: .BLKW R$$L11*6 ;PARAMETER SAVE AREA FOR WRITE CHECK VC$DL = 0 ; ; EXECUTIVE ENTRY POINT VECTOR TABLE ; EXEVEC: .WORD 0 ; FLAG FOR VECTOR NOT YET FILLED ALOCB: .WORD $ALOCB BLKC2: .WORD $BLKC2 BMSET: .WORD $BMSET CVLBN: .WORD $CVLBN DEACB: .WORD $DEACB DTOER: .WORD $DTOER DVERR: .WORD $DVERR ERRSQ: .WORD $ERRSQ FORK: .WORD $FORK FMASK: .WORD $FMASK GTPKT: .WORD $GTPKT IODON: .WORD $IODON MPUBM: .WORD $MPUBM RLCN: .WORD $RLCN RQCND: .WORD $RQCND STMAP: .WORD $STMAP SGFIN: .WORD $SGFIN VOLVD: .WORD $VOLVD ; KISR6: .WORD KISAR6 ; SCTM: .WORD S.CTM SITM: .WORD S.ITM SKRB: .WORD S.KRB SOWN: .WORD S.OWN SPKT: .WORD S.PKT SSTS: .WORD S.STS SST2: .WORD S.ST2 ; EXEVCL=<<<.-EXEVEC>/2>-1> ; S.VCTM = -1 S.VITM = -1 S.VKRB = -1 S.COWN = -1 S.VPKT = -1 S.VSTS = -1 S.VST2 = -1 ; ; SCB REFERENCE PATCH TABLE ; SCBPAT: .WORD CTM1,SCTM .WORD CTM2,SCTM .WORD CTM3,SCTM .WORD CTM4,SCTM .WORD ITM1,SITM .WORD ITM2,SITM .WORD ITM3,SITM .WORD RKRB1,SKRB .WORD KRB1,SKRB .WORD KRB2,SKRB .WORD KRB3,SKRB .WORD KRB4,SKRB .WORD KRB5,SKRB .WORD KRB6,SKRB .WORD KRB7,SKRB .WORD KRB10,SKRB .WORD KRB11,SKRB .WORD KRB12,SKRB .WORD KRB13,SKRB .WORD KRB14,SKRB .WORD PKT1,SPKT .WORD PKT2,SPKT .WORD PKT3,SPKT .WORD PKT4,SPKT .WORD PKT5,SPKT .WORD PKT6,SPKT .WORD PKT7,SPKT .WORD STS1,SSTS .WORD STS2,SSTS .WORD STS3,SSTS .WORD STS4,SSTS .WORD RST21,SST2 .WORD 0 ;END OF THE TABLE ; ; ;DRIVER DISPATCH TABLE ; DDT$ DL,R$$L11,NEW=Y,OPT=Y ;GENERATE DISPATCH TABLE ;+ ; **-DLINI-RL11/RL01 DISK CONTROLLER INITIATOR ; ; THIS ROUTINE IS ENTERED FROM THE QUEUE I/O DIRECTIVE WHEN AN I/O ; REQUEST IS QUEUED AND AT THE END OF A PREVIOUS I/O OPERATION TO ; PROPAGATE THE EXECUTION OF THE DRIVER. IF THE SPECIFIED CONTROLLER ; IS NOT BUSY, THEN AN ATTEMPT IS MADE TO DEQUEUE THE NEXT I/O REQUEST. ; ELSE A RETURN TO THE CALLER IS EXECUTED. IF THE DEQUEUE ATTEMPT ; IS SUCCESSFUL, THEN THE NEXT I/O OPERATION IS INITIATED. A RETURN ; TO THE CALLER IS THEN EXECUTED. ; ; INPUTS: ; R5= ADRS OF THE UCB OF THE CONTROLLER TO BE INITIATED. ; ; OUTPUTS: ; IF THE SPECIFIED CONTROLLER IS NOT BUSY AND AN I/O REQUEST IS ; WAITING TO BE PROCESSED, THEN THE REQUEST IS DEQUEUED AND THE ; DRIVER INITIATES THE REQUESTED I/O FUNCTION ;- DLINI: GTPKT$ DL,R$$L11 ;GET NEXT I/O PACKET TO PROCESS ; ; THE FOLLOWING ARGUMENTS ARE RETURNED BY $GTPKT: ; ; R1= ADRS OF THE I/O REQUEST PACKET ; R2= PHYSICAL UNIT NUMBER OF THE REQUESTED DRIVE ; R3= CONTROLLER INDEX ; R4= ADRS OF THE STATUS CONTROL BLOCK (SCB) ; R5= ADRS OF THE UCB OF THE DRIVE TO BE INITIATED ; ; RL11/RL01 DISK CONTROLLER I/O REQUEST PACKET FORMAT: ; ; WD. 00 -- I/O QUEUE THREAD WORD ; WD. 01 -- REQUEST PRIORITY, EVENT FLAG NUMBER ; WD. 02 -- ADRS OF THE TCB OF THE REQUESTOR TASK ; WD. 03 -- POINTER TO 2ND LUN WORD IN REQUESTOR TASK HEADER ; WD. 04 -- CONTENTS OF FIRST LUN WORD (UCB ADRS) ; WD. 05 -- I/O FUNCTION CODE ; WD. 06 -- VIRTUAL ADRS OF I/O STATUS BLOCK ; WD. 07 -- RELOCATION BIAS OF I/O STATUS BLOCK ; WD. 10 -- I/O STATUS BLOCK ADDRESS (DISPLACEMENT +140000) ; WD. 11 -- VIRTUAL ADRS OF AST SERVICE ROUTINE ; WD. 12 -- MEMORY EXTENSION BITS OF I/O TRANSFER ; WD. 13 -- BUFFER ADRS OF I/O TRANSFER ; WD. 14 -- NUMBER OF BYTES TO BE TRANSFERED ; WD. 15 -- NOT USED. ; WD. 16 -- LOW BYTE MUST BE ZERO AND HIGH BYTE IS NOT USED ; WD. 17 -- LOW PART OF LOGICAL BLK NUMBER OF I/O REQUEST ; WD. 20 -- RELOCATION BIAS OF DIAGNOSTIC REG. BLK. ELSE NOT USED ; WD. 21 -- DIAGN. REG. BLOCK ADDRESS (DISPL.+140000) ELSE NOT USED ; ; DRIVER USAGE OF WORDS IN I/O PACKET: ; I.PRM+6 (WD. 15) - EXTENDED ADDRESS BITS ; I.PRM+10 (WD. 16) - CYLINDER # OR DESIRED DISK ADDRESS ; I.PRM+12 (WD. 17) - SECTOR/SURFACE # OR BYTES REMAINING TO XFER ; CALL @RQCND ;REQUEST ACCESS TO CONTROLLER MOV S.VPKT(R4),R1 ;GET I/O PACKET ADDRESS PKT1=.-2 MOV S.VKRB(R4),R3 ;GET KRB ADDRESS KRB1=.-2 BIS #KS.DIP,K.STS(R3) ;MARK CONTROLLER AS DATA TRANSFER IN PROGRESS MOVB K.CON(R3),R3 ;RETRIEVE CONTROLLER INDEX MOV #RETRY,RTTBL(R3);SET INITIAL RETRY COUNT CALL DLVV ;PROCESS VOLUME VALID FUNCTIONS BIT #FE.EXT,@FMASK ;IS THIS A 22-BIT SYSTEM BEQ 15$ ;IF EQ NO BIT #DV.EXT,U.CW1(R5) ;DOES THE RLBAE EXIST? BEQ 10$ ;IF EQ NO MOVB U.BUF+1(R5),R0 ;GET EXTENDED ADDRESS BITS MOV R0,I.PRM+6(R1) ;SAVE THEM FOR LATER ASH #4,R0 ;PUT THEM IN THE RIGHT PLACE BIC #^C<60>,R0 ;JUST GET THE LOW 2 BITS MOV R0,U.BUF(R5) ;SAVE THEM BR 15$ ; 10$: CALL @STMAP ;SETUP UNIBUS MAPPING REGISTERS CALL @MPUBM ;MAP UNIBUS TO MEMORY 15$: MOV S.VPKT(R4),R1 ;GET I/O PACKET ADDRESS PKT2=.-2 MOVB U.UNIT(R5),U.BUF+1(R5) ;SET UNIT NUMBER MOV #IE.IFC&377,R0 ;ASSUME ILLEGAL FUNCTION BIS #READ!IE,U.BUF(R5) ;ASSUME READ LOGICAL FUNCTION CMPB #IO.RLB/^D<256>,I.FCN+1(R1) ;REALLY? BHIS 20$ ;IF HIS FUNCTION IS LEGAL CALLR DLFIN ;FUNCTION IS ILLEGAL 20$: BEQ 25$ ;IF EQ FUNCTION IS A READ SUB #WRITE,U.BUF(R5) ;CONVERT TO WRITE LOGICAL FUNCTION 25$: MOV I.PRM+12(R1),R0 ;RETRIEVE SECTOR AND SURFACE MOV I.PRM+10(R1),R2 ;RETRIEVE CYLINDER NUMBER ASH #7,R2 ;PUT IT IN POSITION BIS R0,R2 ;MERGE IN THE SECTOR AND SURFACE MOV R2,I.PRM+10(R1) ;SAVE DESIRED DISK ADDRESS BIC #^C<77>,R0 ;ISOLATE SECTOR NUMBER MOV U.CNT(R5),I.PRM+12(R1) ;ASSUME ONLY ONE XFER NEEDED MOV #^D<40>,R2 ;SET SECTORS PER SURFACE SUB R0,R2 ;CALCULATE SECTORS LEFT ON SURFACE SWAB R2 ;GET BYTES LEFT ON SURFACE CMP U.CNT(R5),R2 ;ARE ADDITIONAL TRANSFERS REQUIRED? BLOS 30$ ;IF LOS NO MOV R2,U.CNT(R5) ;SET BYTE COUNT FOR FIRST TRANSFER 30$: MOV S.VKRB(R4),R3 ;GET KRB ADDRESS KRB2=.-2 MOVB K.CON(R3),R3 ;RETRIEVE CONTROLLER INDEX MUL #6,R3 ;FORM AN INDEX INTO PARAMETER SAVE AREA ADD #PRMSV,R3 ;POINT TO THIS ENTRY MOV U.BUF(R5),(R3)+ ;SAVE INITIAL PARAMETERS MOV U.BUF+2(R5),(R3)+ ;... MOV U.CNT(R5),(R3)+ ;... MOV I.PRM+10(R1),(R3)+ ;... MOV I.PRM+12(R1),(R3)+ ;... MOV I.PRM+6(R1),(R3)+ ;... ;+ ; THIS SECTION WILL INITIATE THE OPERATION ;- DLINIO: MOV @S.VKRB(R4),R2 ;RETREIVE CSR ADDRESS KRB3=.-2 MOV S.VPKT(R4),R3 ;GET ADDRESS OF I/O PACKET PKT3=.-2 CLRB U.CW2+1(R5) ;CLEAR DRIVE FLAGS BITB #US.VV,U.STS(R5) ;IS SOFTWARE VOLUME VALID SET? BEQ 5$ ;IF EQ NO CALL DLGST ;GET DRIVE STATUS BR 6$ ;SKIP RESET 5$: CALL DLRST ;RESET DRIVE AND GET STATUS 6$: MOV RLMP(R2),R1 ;GET THE STATUS INFO BIC #WLS!DT!HSS,R1 ;REMOVE IRRELEVANT BITS BIT #DRDY,(R2) ;IS THE DRIVE READY? BEQ 20$ ;IF EQ NO BITB #US.VV,U.STS(R5);IS SOFTWARE VOLUME VALID SET? BEQ 10$ ;IF EQ NO BIT #VC,R1 ;IS VOLUME CHECK SET? BNE 20$ ;IF NE ERROR OR POWERFAIL RECOVERY CALL DLRST ;CLEAR ANY OTHER DRIVE ERROR CONDITIONS MOV RLMP(R2),R1 ;GET THE STATUS INFO BIC #WLS!DT!HSS,R1 ;REMOVE IRRELEVANT BITS BIT #DRDY,(R2) ;IS THE DRIVE READY? BEQ 20$ ;IF EQ NO 10$: CMP #HH!BH!SLM,R1 ;HEADS, BRUSHES AND STATE OK? BEQ 35$ ;IF EQ YES 20$: BITB #US.SPU,U.STS(R5) ;IS THE DRIVE SPINNING UP? BNE DLPWF1 ;IF NE YES, WAIT FOR IT TO SPIN UP CALL DLDVER ;LOG DRIVE NOT READY ERROR 25$: MOV #IE.DNR&377,R0 ;SET RETURN ERROR CODE CALLR DLFIN ;EXIT FATAL 30$: CALL DLRST ;RESET DRIVE ERRORS 35$: BICB #US.SPU,U.STS(R5) ;RESET DRIVE SPINNING UP MOV I.PRM+10(R3),R0 ;RETREIVE STARTING DISK ADDRESS CALL DLDIFF ;CALCULATE DIFFERENCE WORD DLGO: BEQ 40$ ;IF EQ NO SEEK IS NECESSARY MOV #SEEK,R1 ;GET CODE FOR SEEK FUNCTION CALL DLXCT ;EXECUTE THE SEEK BMI DLEROR ;IF MI ERROR DURING SEEK FUNCTION 40$: MOVB S.VITM(R4),S.VCTM(R4) ;SET TIMEOUT COUNT ITM1=.-4 CTM1=.-2 BIT #DV.EXT,U.CW1(R5) ;DOES THE RLBAE EXIST? BEQ 45$ ;IF EQ NO MOV I.PRM+6(R3),RLBAE(R2) ;LOAD EXTENDED ADDRESS BITS 45$: ADD #RLMP,R2 ;POINT TO RLMP MOV U.CNT(R5),R1 ;GET BYTE COUNT ROR R1 ;MAKE IT A WORD COUNT NEG R1 ;ALSO NEGATIVE MOV R1,(R2) ;LOAD WORD COUNT MOV I.PRM+10(R3),-(R2) ;LOAD STARTING DISK ADDRESS MOV U.BUF+2(R5),-(R2) ;LOAD BUS ADDRESS CALL @BMSET ;SET I/O ACTIVE BIT IN MAP MOV U.BUF(R5),-(R2) ;;;LOAD FUNCTION AND GO ;+ ; CANCEL I/O OPERATION IS A NOP FOR FILE STRUCTURED DEVICES. ;- DLCAN: RETURN ;;;NOP FOR RL11 ;+ ; POWERFAIL IS HANDLED VIA THE DEVICE TIMEOUT FACILITY AND ; CAUSES NO IMMEDIATE ACTION ON THE UNIT. THE CURRENT TIMEOUT ; COUNT IS EXTENDED SO THAT IF THE UNIT WAS BUSY IT WILL HAVE ; SUFFICIENT TIME TO SPIN BACK UP. THE NEXT I/O REQUEST TO ANY ; UNIT WILL BE SUSPENDED FOR AT LEAST THE EXTENDED TIMEOUT UNLESS ; THE UNIT IS ALREADY READY. ;- DLPWF: BCS DLCAN ;IGNORE CONTROLLER POWERFAIL CALL TSTB S.VSTS(R4) ;IS DRIVE CURRENTLY BUSY STS1=.-2 BEQ DLPWF2 ;IF EQ NO MOVB #4,S.VSTS(R4) ;ALLOW FOR A FULL MINUTE TO SPIN UP STS2=.-2 DLPWF1: MOVB #RLSPU,S.VCTM(R4);EXTEND TIMEOUT FOR UNIT CTM2=.-2 DLPWF2: BISB #US.SPU,U.STS(R5) ;SET UNIT SPINNING UP RETURN ; ;+ ; **-$DLINT-RL11/RL01 DISK CONTROLLER ; INTERRUPT AND ERROR SERVICE ROUTINES ;- INTSE$ DL,PR5,R$$L11 ;;;SAVE REGISTERS AND SET PRIORITY CALL @FORK ;;;CREATE A SYSTEM PROCESS MOV U.SCB(R5),R4 ;RETRIEVE SCB ADDRESS BITB #RVSK,U.CW2+1(R5) ;REVERSE SEEK IN PROGRESS? BEQ 5$ ; JMP DLIO1 ;IF NE YES 5$: MOV @S.VKRB(R4),R2 ;RETRIEVE CSR ADDRESS KRB4=.-2 MOV #IS.SUC&377,R0 ;ASSUME SUCCESSFUL OPERATION MOV S.VPKT(R4),R3 ;RETRIEVE I/O PACKET ADDRESS PKT4=.-2 MOV (R2),R1 ;GET CONTENTS OF RLCS BMI DLEROR ;IF MI AN ERROR OCCURRED SUB U.CNT(R5),I.PRM+12(R3) ;GET BYTES LEFT TO TRANSFER BEQ DLPASS ;IF EQ NONE LEFT MOV I.PRM+12(R3),U.CNT(R5) ;ASSUME LAST TRANSFER COMING CMP I.PRM+12(R3),#RLBPT ;IS THIS THE LAST TRANSFER? BLOS 10$ ;IF LOS YES MOV #RLBPT,U.CNT(R5);TRANSFER A WHOLE TRACKS WORTH 10$: BIC #CRDY,R1 ;CLEAR CRDY TO START FUNCTION MOV R1,U.BUF(R5) ;SAVE CURRENT FUNCTION AND ADDRESS BITS MOV RLBA(R2),U.BUF+2(R5) ;SAVE CURRENT BUS ADDRESS BIT #DV.EXT,U.CW1(R5) ;DOES THE RLBAE EXIST? BEQ 20$ ;IF EQ NO MOV RLBAE(R2),I.PRM+6(R3) ;SAVE EXTENDED ADDRESS BITS 20$: MOV I.PRM+10(R3),R0 ;GET INITIAL DISK ADDRESS MOV R0,R1 ;COPY DISK ADDRESS BIS #77,R0 ;UPDATE CYLINDER AND SURFACE ... INC R0 ;... LEAVING SECTOR BITS ZERO MOV R0,I.PRM+10(R3) ;SAVE NEW DISK ADDRESS CALL DLDIF0 ;CALCULATE MID-TRANSFER DIFFERENCE CALLR DLGO ;GO DO THE OPERATION DLEROR: BIT #DRDY,R1 ;IS THE DRIVE READY? BEQ 25$ ;IF NE YES MOV RLMP(R2),R1 ;GET THE STATUS INFO BIC #WLS!DT!HSS,R1 ;REMOVE IRRELEVANT BITS CMP #HH!BH!SLM,R1 ;HEADS, BRUSHES AND STATE OK? BEQ DLERR ;YES, THEN DO RETRY 25$: MOVB S.VITM(R4),S.VCTM(R4);WAIT FOR DRIVE TO QUIESCE ITM2=.-4 CTM3=.-2 MOVB #SDWN,U.CW2+1(R5) ;FLAG SETTLE DOWN IN PROGRESS RETURN ; DLERR: MOV (R2),R1 ;RETRIEVE CONTENTS OF RLCS BITB #IQ.UMD,I.FCN(R3) ;DIAGNOSTIC FUNCTION? BNE DLPASS ;IF NE YES, GO PASS REGISTERS MOV R1,-(SP) ;SAVE RLCS CONTENTS CALL DLDVER ;LOG DEVICE ERROR MOV (SP),R1 ;RETRIEVE CONTENTS OF RLCS MOV #IE.BBE&377,R0 ;ASSUME BAD BLOCK ERROR COM (SP) ;TOGGLE THE BITS BIT #HCRC!OPI,(SP)+ ;BAD BLOCK ERROR? BEQ DLFIN ;IF EQ YES MOV #IE.VER&377,R0 ;ASSUME UNRECOVERABLE ERROR BIT #NXM,R1 ;NON-EXISTANT MEMORY? BNE DLFIN ;IF NE YES BIT #DE,R1 ;DRIVE PROBLEMS? BEQ 50$ ;IF EQ NO CALL DLGST ;EXECUTE GET DRIVE STATUS FUNCTION BIT #WGE,RLMP(R2) ;WRITE GATE ERROR? BEQ DLFIN ;IF EQ NO BIT #WLS,RLMP(R2) ;IS THE DRIVE WRITE LOCKED? BEQ DLRTY ;IF EQ NO MOV #IE.WLK&377,R0 ;SET WRITE LOCK ERROR CODE BR DLFIN ; 50$: BIT #10,U.BUF(R5) ;WRITE CHECK FUNCTION? BNE DLRTY ;IF NE NO BIT #OPI,R1 ;OPERATION INCOMPLETE? BNE DLRTY ;IF NE YES BIT #DCK,R1 ;WRITE CHECK ERROR? BEQ DLRTY ;IF EQ NO MOV #IE.WCK&377,R0 ;YES, SET WRITE CHECK ERROR CODE DLRTY: MOV S.VPKT(R4),R1 ;RETRIEVE I/O PACKET ADDRESS PKT5=.-2 BITB #IQ.X,I.FCN(R1) ;INHIBIT RETRIES? BNE DLFIN ;IF NE YES MOV S.VKRB(R4),R3 ;RETRIEVE KRB ADDRESS KRB5=.-2 MOVB K.CON(R3),R3 ;GET CONTROLLER INDEX DECB RTTBL(R3) ;ANY MORE RETRIES LEFT? BLE DLFIN ;IF LE NO DLIO: CALL DLRST ;RESET DRIVE ERRORS DLIO1: JMP DLINIO ;RETRY ENTIRE OPERATION DLPASS: BITB #IQ.UMD,I.FCN(R3) ;DIAGNOSTIC FUNCTION? BEQ 10$ ;IF EQ NO MOV I.PRM+14(R3),@KISR6;SET BUFFER RELOCATION BIAS MOV I.PRM+16(R3),R3 ;GET REGISTER BUFFER ADDRESS CALL REGPAS ;MOVE REGISTERS INTO BUFFER BR DLFIN ;EXIT 10$: BITB #IO.WLC&377,I.FCN(R3) ;WRITE WITH WRITE CHECK? BNE 20$ ;IF NE YES BITB #US.WCK,U.STS(R5) ;WRITE CHECK ENABLED? BEQ DLFIN ;IF EQ NO 20$: MOV U.BUF(R5),R1 ;GET CURRENT FUNCTION CODE BIT #WCHK,R1 ;WRITE OR WRITE CHECK FUNCTION? BEQ DLFIN ;IF EQ NO BIT #10,R1 ;WAS FUNCTION WRITE CHECK? BEQ DLFIN ;IF EQ YES MOV S.VKRB(R4),R1 ;GET KRB ADDRESS KRB6=.-2 MOVB K.CON(R1),R1 ;RETRIEVE CONTROLLER INDEX MOV #RETRY,RTTBL(R1);RESET RETRY COUNT MUL #6,R1 ;FORM AN INDEX INTO PARAMETER SAVE AREA ADD #PRMSV,R1 ;... MOV (R1)+,U.BUF(R5) ;RESTORE STARTING PARAMETERS MOV (R1)+,U.BUF+2(R5) ;... MOV (R1)+,U.CNT(R5) ;... MOV (R1)+,I.PRM+10(R3) ;... MOV (R1)+,I.PRM+12(R3) ;... MOV (R1)+,I.PRM+6(R3) ;... BIC #10,U.BUF(R5) ;CONVERT TO WRITE CHECK FUNCTION BR DLIO ;START THE WRITE CHECK DLFIN: MOV S.VPKT(R4),R2 ;GET ADDRESS OF I/O PACKET PKT6=.-2 MOV I.PRM+4(R2),R1 ;GET TOTAL TRANSFER SIZE SUB I.PRM+12(R2),R1 ;CALCULATE BYTES TRANSFERED MOV S.VKRB(R4),R3 ;GET KRB ADDRESS KRB7=.-2 BIC #KS.DIP,K.STS(R3) ;DATA TRANSFER OVER MOVB K.CON(R3),R3 ;RETRIEVE CONTROLLER INDEX MOVB RTTBL(R3),R2 ;GET FINAL RETRY COUNT BIS #RETRY*^D<256>,R2 ;MERGE STARTING RETRY COUNT CALL @RLCN ;RELEASE THE CONTROLLER CALL @IODON ;FINISH I/O OPERATION JMP DLINI ;PROCESS NEXT REQUEST ;+ ; **-DLOUT-RL11/RL01 DISK CONTROLLER ; DEVICE TIMEOUT ROUTINE ; ; DEVICE TIMEOUT RESULTS IN THE OPERATION BEING REPEATED. ; TIMEOUTS ARE USUALLY CAUSED BY A POWER FAILURE BUT MAY ALSO ; BE THE RESULT OF A HARDWARE MALFUNCTION. ;- DLOUT: MOV S.VPKT(R4),R3 ;;;RETRIEVE I/O PACKET ADDRESS PKT7=.-2 BITB #US.SPU,U.STS(R5) ;;;IS DRIVE SPINNING UP? BEQ 20$ ;;;IF EQ NO DECB S.VSTS(R4) ;;;HAVE WE WAITED A MINUTE YET? STS3=.-2 BNE 10$ ;;;IF NE NO INCB S.VSTS(R4) ;;;LEAVE CONTROLLER BUSY STS4=.-2 BR 30$ ;;;LOG DEVICE TIMEOUT 10$: MTPS #0 ;;;ALLOW INTERRUPTS BR DLIO ;RETRY ENTIRE OPERATION 20$: BITB #SDWN,U.CW2+1(R5) ;;;IS DRIVE SETTLING DOWN? BEQ 30$ ;;;IF EQ NO MTPS #0 ;;;YES, ALLOW INTERUPTS JMP DLERR ;PROCESS THE ERROR 30$: MTPS #0 ;;;ALLOW INTERRUPTS BITB #IQ.UMD,I.FCN(R3) ;DIAGNOSTIC FUNCTION? BNE DLPASS ;IF NE YES, GO PASS REGISTERS CALL DLDTER ;LOG DEVICE TIMEOUT MOV #IE.DNR&377,R0 ;SET DEVICE NOT READY JMP DLRTY ;RETRY OPERATION ;+ ; **-DLXCT,DLGST,DLRST-RL11/RL01 DISK CONTROLLER ; FUNCTION EXECUTION ROUTINES ; ; THIS ROUTINE WILL EXECUTE A GET DRIVE STATUS OR ANY ; NON-INTERRUPTABLE FUNCTION AND WAIT FOR ITS COMPLETION. ; ; INPUTS: ; R1 = FUNCTION CODE ; R2 = CSR ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; R1 = CONTENTS OF RLCS (TESTED) ; FUNCTION EXECUTED ;- DLRST: MOV #RST!STS!MRK,RLDA(R2) ;SET MESSAGE CODES IN RLDA CALL DLDST ;DO THE DRIVE RESET FIRST DLGST: MOV #STS!MRK,RLDA(R2) ;SET MESSAGE CODES IN RLDA DLDST: MOV #GSTS,R1 ;SET GET STATUS FUNCTION DLXCT: MOV R1,-(SP) ;SAVE FUNCTION CODE MOVB U.UNIT(R5),1(SP);MERGE CURRENT DRIVE BITS MOV (SP)+,(R2) ;LOAD RLCS 10$: BIT #ERR!CRDY,(R2) ;FUNCTION COMPLETE OR ERROR? BEQ 10$ ;IF EQ NO MOV (R2),R1 ;SAVE RLCS AND TEST FOR ERRORS RETURN ; ;+ ; **-DLDIFF-RL11/RL01 DISK CONTROLLER ; CYLINDER ADDRESS DIFFERENCE CALCULATOR ; ; THIS SUBROUTINE CALCULATES THE DIFFERENCE WORD USED IN THE ; SEEK OPERATION. IF A HEADER CANNOT BE READ AFTER 16. RETRIES, ; AN ERROR WILL BE LOGGED AND A ONE CYLINDER REVERSE SEEK WILL BE ; ISSUED. THE SEEK IS FOLLOWED BY A READ HEADERS TO CAUSE AN ; INTERRUPT. ; ; INPUTS: ; R0 = DESIRED DISK ADDRESS ; ; OUTPUTS: ; R1 = DIFFERENCE WORD ; RLDA = LOADED WITH DIFFERENCE WORD ; IF EQ NO SEEK IS NECESSARY ;- DLDIFF: MOV #RETRY*2,-(SP) ;SET READ HEADER RETRY COUNT 10$: MOV #RDH,R1 ;CODE FOR READ HEADERS FUNCTION CALL DLXCT ;EXECUTE THE FUNCTION BPL 20$ ;IF PL FUNCTION EXECUTED OK DEC (SP) ;ANY RETRIES LEFT? BGT 10$ ;IF GT YES CMP (SP)+,(SP)+ ;REMOVE RETRY COUNT AND CALLERS ADDRESS CALL DLDVER ;LOG HEADER ERROR CALL DLRST ;RESET DRIVE MOV #REV,RLDA(R2) ;LOAD REVERSE SEEK DIFFERENCE WORD MOV #SEEK,R1 ;GET CODE FOR SEEK FUNCTION MOV #IE.VER&377,R0 ;ASSUME THE SEEK WILL FAIL CALL DLXCT ;EXECUTE THE SEEK BMI DLFIN ;IF MI WE FAILED BIC #^C,R1 ;GET ONLY UNIT SELECT BITS BIS #IE!RDH,R1 ;LOAD CODES FOR READ HEADER MOVB #RVSK,U.CW2+1(R5) ;INDICATE REVERSE SEEK IN PROGRESS MOVB S.VITM(R4),S.VCTM(R4) ;SET DEVICE TIMEOUT COUNTER ITM3=.-4 CTM4=.-2 MOV R1,(R2) ;LOAD FUNCTION AND GO RETURN ;WAIT FOR THE INTERRUPT 20$: TST (SP)+ ;REMOVE RETRY COUNT MOV RLMP(R2),R1 ;RETREIVE HEADER WORD DLDIF0: BIC #77,R0 ;MASK OUT SECTOR BITS BIC #77,R1 ;... CMP R0,R1 ;DO WE NEED TO DO A SEEK? BEQ 40$ ;IF EQ NO MOV R0,-(SP) ;SAVE DESIRED DISK ADDRESS BIC #^C<100>,(SP) ;ISOLATE SURFACE BIT ASR (SP) ;PUT INTO THE PROPER POSITION ASR (SP) ;... BIC #100,R0 ;REMOVE SURFACE BIT BIC #100,R1 ;... SUB R0,R1 ;SUBTRACT DESIRED FROM ACTUAL ; BEQ 30$ ;IF EQ ONLY CHANGE SURFACE BCC 30$ ;IF CC ACTUAL .GE. DESIRED NEG R1 ;ACTUAL < DESIRED, MAKE POSITIVE DIFFERENCE BIS #SN,R1 ;SET SIGN FOR MOVE TO CENTER OF DISK 30$: INC R1 ;SET MARKER BIT BIS (SP)+,R1 ;MERGE IN SURFACE BIT MOV R1,RLDA(R2) ;LOAD DIFFERENCE WORD 40$: RETURN ; ;+ ; **-DLDXXX-RL11/RL01 DISK CONTROLLER ; ERROR LOGGING ROUTINES ; ; THIS ROUTINE IS CALLED WHENEVER A DEVICE ERROR OR DEVICE TIMEOUT ; OCCURS. A CORE BLOCK THE SIZE OF THE REGISTER BUFFER IS ALLOCATED ; AND THE UNIBUS REGISTERS ALONG WITH THE DRIVE STATUS INFORMATION ; ARE TRANSFERED INTO THE CORE BLOCK AND THE APPROPRIATE EXECUTIVE ; ERROR LOGGING ROUTINE IS CALLED. FINALLY, THE CORE BLOCK IS ; DEALLOCATED AND THE CSR AND CONTROLLER INDEX ARE RESTORED. ; ; IF FOR ANY REASON THE CORE BLOCK CANNOT BE ALLOCATED THEN THE ; EXECUTIVE ERROR LOGGING ROUTINE WILL NOT BE CALLED AND THE ERROR ; SEQUENCE NUMBER WILL BE UPDATED TO INDICATE THAT A MISSED ERROR ; CONDITION OCCURRED. ; ; INPUTS: ; R2 = CSR ADDRESS ; R4 = SCB ADDRESS ; ; OUTPUTS: ; R0, R1 ARE DESTROYED ; R3 = CONTROLLER INDEX ;- .ENABL LSB DLDVER: MOV DVERR,-(SP) ;ADDRESS OF EXEC ERROR ROUTINE BR 10$ ; DLDTER: MOV DTOER,-(SP) ;ADDRESS OF EXEC TIMEOUT ROUTINE 10$: MOV #RLCNT*2,R1 ; GET NUMBER OF BYTES TO ALLOCATE CALL @ALOCB ;ALLOCATE A CORE BLOCK BCC 20$ ;IF CC BLOCK WAS ALLOCATED INC @ERRSQ ;INDICATE A MISSED ERROR CONDITION CMP (SP)+,DTOER ;ALLOCATION FAILURE, TIMEOUT IN PROGRESS? BNE 30$ ;IF NE NO MOV @S.VKRB(R4),R2 ;RETRIEVE CSR ADDRESS KRB10=.-2 BIC #IE,(R2) ;;;CLEAR INTERRUPT ENABLE MTPS #0 ;;;ALLOW INTERRUPTS BR 30$ ;DON'T LOG ERROR IF ALLOCATION FAILURE 20$: MOV R0,R3 ;SET POINTER TO CORE BLOCK MOV @S.VKRB(R4),R2 ;GET CSR ADDRESS KRB11=.-2 CALL REGPAS ;MOVE REGISTERS INTO CORE BLOCK MOV R0,R2 ;COPY CORE BLOCK ADDRESS CALL @(SP)+ ;CALL EXEC ERROR LOGGING ROUTINE MOV R2,R0 ;GET BACK CORE BLOCK ADDDRESS MOV #RLCNT*2,R1 ;GET NUMBER OF BYTES TO DEALLOCATE CALL @DEACB ;DEALLOCATE THE CORE BLOCK 30$: MOV S.VKRB(R4),R3 ;GET KRB ADDRESS KRB12=.-2 MOV (R3),R2 ;RETRIEVE CSR ADDRESS MOVB K.CON(R3),R3 ;RETRIEVE CONTROLLER INDEX RETURN .DSABL LSB ;+ ; MOVE THE CONTROLLER/DRIVE REGISTERS INTO THE SPECIFIED BUFFER. ; ; INPUTS: ; R2 = CSR ADDRESS ; R3 = BUFFER ADDRESS ;- REGPAS: MOV (R2),(R3)+ ;MOVE RLCS MOV RLBA(R2),(R3)+ ;MOVE RLBA MOV RLDA(R2),(R3)+ ;MOVE RLDA MOV RLMP(R2),(R3)+ ;MOVE RLMP CLR (R3)+ ;ASSUME NO RLBAE BIT #DV.EXT,U.CW1(R5) ;DOES THE RLBAE EXIST? BEQ 10$ ;IF EQ NO MOV RLBAE(R2),-2(R3);MOVE RLBAE 10$: CLR (R3)+ ;EXTRA WORD IS BLANK CALL DLGST ;EXECUTE GET DRIVE STATUS FUNCTION MOV RLMP(R2),(R3) ;SAVE DRIVE STATUS RETURN ; ;+ ; **-DLVV-PROCESS VOLUME VALID FUNCTIONS ; ; THIS ROUTINE WILL VALIDATE VOLUME VALID AND HANDLE DEVICE ; SPECIFIC VOLUME VALID AND SIZING FUNCTIONS. ; ; INPUTS: ; R1 = I/O PACKET ADDRESS ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; IF THIS IS A TRANSFER FUNCTION ONLY R0 IS DESTROYED. ; IF THIS IS A VOLUME VALID FUNCTION, THE PROPER ACTION ; IS TAKEN AND CONTROL IS TRANSFERED DIRECTLY TO THE ; PROPER PLACE IN THE DRIVER. ;- DLVV: CALL @VOLVD ;VALIDATE VOLUME VALID BCS 20$ ;IF CS WE FAILED TST R0 ;IS THIS A TRANSFER FUNCTION? BMI 40$ ;IF MI YES MOV @S.VKRB(R4),R2 ;GET CSR ADDRESS KRB13=.-2 MOV R1,R3 ;COPY I/O PACKET ADDRESS CALL DLRST ;RESET DRIVE AND GET STATUS TST I.PRM+2(R3) ;SIZE THE DISK? BPL 10$ ;IF PL NO TST (SP)+ ;REMOVE RETURN MOV #IE.SZE&377,R0 ;ASSUME NON-EXISTANT DRIVE MOV (R2),R1 ;GET CONTENTS OF RLCS BIC #^C,R1 ;GET RID OF UNWANTED BITS CMP #ERR!OPI,R1 ;DOES THE DRIVE EXIST? BEQ 30$ ;IF EQ NO MOV #IS.SUC&377,R0 ;YES, ASSUME SUCCESS CALLR DLPASS ;PASS REGISTERS AND EXIT 10$: BIT #VV$SET,I.PRM+2(R3) ;SET VOLUME VALID? BEQ 25$ ;IF EQ NO MOV RLMP(R2),R1 ;GET THE STATUS INFORMATION BIT #DRDY,(R2) ;IS THE DRIVE READY? BEQ 15$ ;IF EQ NO BIC #WLS!DT!HSS,R1 ;REMOVE IRRELEVANT BITS CMP #HH!BH!SLM,R1 ;HEADS, BRUSHES AND STATE OK? BEQ 25$ ;IF EQ YES 15$: MOV #IE.DNR&377,R0 ;SET DRIVE NOT READY 20$: BICB #US.VV,U.STS(R5) ;CLEAR SOFTWARE VOLUME VALID 25$: TST (SP)+ ;REMOVE RETURN 30$: CALLR DLFIN ;FINISH UP 40$: RETURN ; ;+ ; **-DLCHK-VALIDATE AND CONVERT THE LBN ; ; THIS ROUTINE IS CALLED FROM $DRQRQ TO DO LBN PROCESSING ; FOR DEVICES WHICH SUPPORT QUEUE OPTIMIZATION. IF BLKC2 ; DETECTS AN ERROR IT WILL RETURN TO THE CORRECT PLACE IN ; $DRQRQ AFTER CALLING $IOALT. ; ; INPUTS: ; R1 = I/O PACKET ADDRESS ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; IF THE CHECKS SUCCEED, THEN THE LBN IN THE I/O PACKET ; IS REPLACED BY THE DISK ADDRESS. R1 IS PRESERVED. ; ; IF THE CHECKS FAIL, THE $IOALT IS ENTERED WITH A FINAL ; STATUS OF IE.BLK AND A RETURN TO THE CORRECT PLACE IN ; $DRQRQ IS EXECUTED. ; ; R0, R2, AND R3 ARE DESTROYED. ; ; NOTE: ALL FUNCTIONS PUT INTO THE DRIVER QUEUE ARRIVE HERE. ; THESE FUNCTIONS INCLUDE, IO.ATT, IO.DET, AND ACP FUNCTIONS. ;- DLCHK: CMPB #IO.ATT/256.,I.FCN+1(R1) ;IS THIS AN ATTACH? BEQ 30$ ;IF EQ YES, LEAVE IT ALONE CMPB #IO.DET/256.,I.FCN+1(R1) ;IS THIS A DETACH? BEQ 30$ ;IF EQ YES, LEAVE IT ALONE MOV I.FCN(R1),-(SP) ;GET FUNCTION CODE BIC #7,(SP) ;REMOVE QUALIFIER BITS CMP #IO.STC,(SP)+ ;IS IT A SET CHARACTERISTICS? BEQ 30$ ;IF EQ YES, LEAVE IT ALONE MOV I.PRM+12(R1),R0 ;RETRIEVE STARTING BLOCK NUMBER MOV R1,R3 ;ASSUME PHYSICAL BLOCK FUNCTION BITB #IO.WPB&377,I.FCN(R1) ;PHYSICAL BLOCK FUNCTION? BNE 20$ ;IF NE YES CALL @BLKC2 ;CHECK LOGICAL BLOCK NUMBER CMPB #IO.WLB/256.,I.FCN+1(R3) ;WRITE FUNCTION? BNE 10$ ;IF NE NO BITB #IO.WLT&377,I.FCN(R3) ;WRITE LAST TRACK FUNCTION? BNE 10$ ;IF NE YES MOV R0,I.PRM+6(R3) ;SAVE STARTING BLOCK NUMBER ADD #20.,(R1) ;ADD 1 TRACKS WORTH OF BLOCKS MOV R3,R1 ;COPY I/O PACKET ADDRESS CALL @BLKC2 ;CHECK LOGICAL BLOCK NUMBER MOV I.PRM+6(R3),R0 ;RESTORE ORIGINAL STARTING BLOCK NUMBER 10$: ASL R0 ;CONVERT BLOCKS TO SECTORS 20$: CLR R2 ;NO HIGH BITS CALL @CVLBN ;CONVERT LBN TO DISK ADDRESS ASH #6,R1 ;POSITION SURFACE BIT BIS R1,R0 ;MERGE SURFACE WITH SECTOR MOV R0,I.PRM+12(R3) ;SAVE SECTOR AND SURFACE ADDRESS MOV R2,I.PRM+10(R3) ;SAVE STARTING CYLINDER ADDRESS MOV R3,R1 ;COPY I/O PACKET ADDRESS 30$: RETURN ; ;+ ; **-DLKRB-CONTROLLER ONLINE/OFFLINE ROUTINE ; ; THIS ROUTINE WILL HANDLE RECONFIGURATION CALLS FOR ONLINE ; CONTROLLER AND OFFLINE CONTROLLER FOR THE RL11, RLV11 AND RLV12. ; ; FOR ONLINE, IT WILL DETERMINE IF THE RLBAE REGISTER EXISTS AND IF ; SO, IT WILL INSURE THAT THE ADDRESS BITS ARE REPLICATED IN THE ; CSR. ; ; FOR OFFLINE, KS.EXT WILL BE CLEARED. ; ; INPUTS: ; R2 = KRB ADDRESS ; R3 = CTB ADDRESS ; C=1 IF OFFLINE REQUEST ; C=0 IF ONLINE REQUEST ; ; OUTPUTS: ; FOR ONLINE, KS.EXT WILL BE SET IF THE CONTROLLER HAS A ; VALID RLBAE. ; FOR OFFLINE, KS.EXT IS CLEARED. ;- DLKRB: BIC #KS.EXT,K.STS(R2) ;ASSUME NO RLBAE BCS 20$ ;IF CS OFFLINE REQUEST TST EXEVEC ;IF DONE ALREADY BNE 2$ ;SKIP THIS MOV R2,-(SP) ;SAVE R2 MOV R3,-(SP) ;SAVE R3 MOV KINAR6,-(SP) ;SAVE KINAR6 MOV @#112,R0 ;GET ADDRESS OF TABLE OF ENTRIES MOV (R0),R0 ;GET ADDRESS OF APR BIAS (1ST WORD IN TABLE) MOV (R0),KINAR6 ;MAP COMMON THROUGH I-SPACE APR6 MOV #EXEVEC,R3 ;POINT TO VECTOR MOV #EXEVCL,R2 ;SPECIFY LENGTH OF VECTOR CALL @#140004 ;TRANSLATE THE VECTOR MOV (SP)+,KINAR6 ;RESTOR KINAR6 MOV (SP)+,R3 ;RESTORE R3 MOV (SP)+,R2 ;RESTORE R2 MOV #SCBPAT,R0 ;GET PATCH TABLE ADDRESS 1$: MOV (R0)+,R1 ;MOVE TABLE ENTRY BEQ 2$ ;IF EQ END OF THE TABLE MOV @(R0)+,(R1) ;IF NEQ START TO PATCH BR 1$ ;COMPLETE IT 2$: BIT #FE.EXT,@FMASK ;IS THIS A 22-BIT SYSTEM? BEQ 20$ ;IF EQ NO CALL @SGFIN ;TURN NXM'S INTO SET CARRY BITS MOV (R2),R4 ;RETREIVE CSR ADDRESS BIS #A16!A17,(R4) ;SET EXTENDED ADDRESS BITS CLR RLBAE(R4) ;CLEAR RLBAE BITS BCS 10$ ;IF CS RLBAE DOES NOT EXIST BIT #A16!A17,(R4) ;DID THE ADDRESS BITS CLEAR? BNE 10$ ;IF NE NO BIS #KS.EXT,K.STS(R2) ;YES, SET RLBAE PRESENT ADD K.OFF(R2),R2 ;CALCULATE OFFSET TO UCB TABLE MOV #RLBAE,KE.RHB(R2) ;SET BAE OFFSET IN DATA BASE 10$: BIC #A16!A17,(R4) ;RESET ADDRESS BITS 20$: RETURN ; ;+ ; **-DLUCB-UNIT ONLINE/OFFLINE ROUTINE ; ; THIS ROUTINE WILL HANDLE RECONFIGURATION CALLS FOR ONLINE ; UNIT AND OFFLINE UNIT FOR RL01 AND RL02 DRIVES. ; ; FOR ONLINE, IF KS.EXT IS SET THEN DV.EXT IS ALSO SET. THIS ; IS DONE TO ELIMINATE UNNECESSARY CODE TO RETREIVE THE KRB ; ADDRESS. ; ; FOR OFFLINE, DV.EXT IS CLEARED. ; ; INPUTS: ; R3 = CONTROLLER INDEX ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; C=1 IF ONLINE REQUEST ; C=0 IF OFFLINE REQUEST ; ; OUTPUTS: ; FOR ONLINE, DV.EXT IS SET IN THE UCB IF KS.EXT IS ; SET IN THE KRB. ; FOR OFFLINE, DV.EXT IS CLEARED. ;- DLUCB: BIC #DV.EXT,U.CW1(R5) ;ASSUME NO RLBAE BCS 10$ ;IF CS OFFLINE REQUEST MOV S.VKRB(R4),R2 ;GET KRB ADDRESS KRB14=.-2 BIT #KS.EXT,K.STS(R2) ;DOES THE RLBAE EXIST? BEQ 10$ ;IF EQ NO BIS #DV.EXT,U.CW1(R5) ;YES, SET BIT IN UCB 10$: RETURN ; .END